/*
Dominique Jannone
Guillaume Marre
Yohan Ojeda
Laurent Schiavon
*/
package controleur;

import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.nio.channels.ServerSocketChannel;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.media.Player;
import javax.media.rtp.RTPManager;

import Econf_Audio.Emetteur_client;
import Econf_Audio.Receveur_client;

import vue.Fenetre;

import model.Conference;
import model.UserClientDelegate;
import model.eConf;

public class CanalUpdateVueConf extends Thread {
	
	private Socket sock;
	private ServerSocketChannel serverSocket;
	private boolean fin;
	private Fenetre fenetre;
	private eConf eConf;
	private boolean isCommunication;
	private Emetteur_client emetteurC;
	//log
	public static final Logger logger = Logger.getLogger(CanalUpdateVueConf.class.getName());
	
	public CanalUpdateVueConf(Fenetre fenetre, eConf eConf) {
		try {
			this.fenetre = fenetre;
			this.eConf = eConf;
			serverSocket = ServerSocketChannel.open();
			serverSocket.socket().bind(new InetSocketAddress(2222));
			isCommunication = false; // Ce n'est pas prit en compte pour le conférencier
		} catch (Exception e) {
			logger.log(Level.SEVERE,e.getClass() + ": " +  e.getMessage(), e);
		}
	}

	public void run() {
//		while (eConf.isClientIsOn()){
		fin = false;
				while (!fin){
				 try {			   
					 logger.log(Level.INFO,"Attente d'une connexion serverSocket.accept()");
						sock =  serverSocket.accept().socket();
						logger.log(Level.INFO,"Après serverSocket.accept()");
						
				    	 Object[][] value = null;
					 
					 
				   // Reception du tableau
				   InputStream is = sock.getInputStream();
				   ObjectInputStream ois = new ObjectInputStream(is);

				   //Parcours (lecture) du tableau reçu taille du prochain tableau
					   Object valueTailleTab = ois.readObject();
					   int nbLignes = new Integer(valueTailleTab.toString());
					   logger.log(Level.INFO,"Réponse du serveur pour la taille tab Update Vue Conf: "+nbLignes);
				  //Parcours (lecture) du tableau reçu : roleUser
					   String roleUser = (String) ois.readObject();
					   
					   logger.log(Level.INFO,"Réponse du serveur role User pour Update Vue Conf: "+roleUser);	
				   				   
				   value = new Object[nbLignes][3];
				   
				   //Parcours (lecture) du tableau reçu
			         for (int i = 0; i < nbLignes; i++) {
			      	   for (int j = 0; j < 3; j++) {
//			      	   value = (Object[][]) ois.readObject();
			      		 Object valueRead = ois.readObject();
			      	   value[i][j] = valueRead;
			      	 logger.log(Level.INFO,"Données dans le tableau :" + valueRead);
			      	   }
			         }
			         
			         logger.log(Level.INFO,"isCommunication: "+isCommunication);
			         logger.log(Level.INFO,"Check cannalUpdateVue:");
			         logger.log(Level.INFO,"DN: "+eConf.getDnUtilisateur());
			         

			         // Check si le conférencier à demander la fin de conférence
			         int finConf = new Integer(value[0][1].toString());
			       if (finConf == Constantes.FIN_CONFERENCE){
			    	// Kill etat de la conférence
						fenetre.getPanneauMenu().isEnableButtonMenu(true);
						fenetre.getPanneauMenu().ButtonConferenceVisible(false);
						// Stop les récepteurs
							// Ferme le player du client
							Player playerClient = Receveur_client.player;
							playerClient.close();
							// get manager de l'emetteur client si exist
							try {
								RTPManager[] emetteur = Emetteur_client.rtpm;
								if (emetteur != null){
									for (int i = 0; i < emetteur.length; i++) {
										emetteur[i].dispose();
									}
									// Close Thread
									eConf.getConference().getEmetteur().closeThread();
								}
							} catch (Exception e) {
//								System.err.println("Err: emetteur[i].dispose(), car il n'existe pas.");
							}
						//set false l'etat de la conférenceonAir
						eConf.setConferenceOnAir(false);
						Conference conference = new Conference(eConf, eConf.getIp_Serveur());
						conference.setFinConference(false);
						conference.start();
//						System.err.println("Fin de conférnce");
						fenetre.afficheFinConference();
					
			       }else{ // le conférencier n'a pas demandé la fin de conférence
			    	// Vérification si je dois couper l'éméteur
				         for (int i = 1; i < value.length; i++) {
//				        	 System.out.println("DN TAb: "+value[i][0]);
				        	 int newValeurMicro = new Integer(value[i][1].toString());
				        	 String dnCourent = eConf.getDnUtilisateur();
				        	 String dnLigne = value[i][0].toString();
//				        	 System.out.println("newValeurMicro: "+newValeurMicro);
//				        	 System.out.println("Constantes.MICRO_SPEAK: "+Constantes.MICRO_SPEAK);
							// On ignore la premiere ligne car les conférenciés gèrent ts seul l'ouverture ou la fermeture de l'Emetteur
				        	 // Kill l'emetteur si il existe
				        	 if (dnLigne.equals(dnCourent) && isCommunication && newValeurMicro != Constantes.MICRO_SPEAK){
				        		 // On demande a l'utilisateur d'erreter de parler
				        		 RTPManager[] emetteur = Emetteur_client.rtpm;
								emetteur[0].dispose();
								// Close Thread
								eConf.getConference().getEmetteur().closeThread();
				        		isCommunication = false;
//				        		System.out.println("Check cannalUpdateVue: Stop Emetteur");
				        	 }
				        	 // Start l'emmeteur si l'utilisateur est en communication
				        	 if (dnLigne.equals(dnCourent) && !isCommunication && newValeurMicro == Constantes.MICRO_SPEAK){
				        		 // Un utilisateur vient d'avoir le droit de parler
//				        		 System.out.println("Ip Serveur: "+eConf.getIp_Serveur());
//				        		 System.out.println("Port d'écoute Serveur: "+eConf.getPortEmetteurDuServeur());
				        		Emetteur_client emetteur = new Emetteur_client(eConf.getPortEmetteurDuServeur(), eConf.getIp_Serveur());
				        		eConf.getConference().setEmetteur(emetteur);
				        		emetteur.start();
				        		isCommunication = true;
//				        		System.out.println("Check cannalUpdateVue: Start Emetteur");
				        	 }
						}
//				         System.out.println("Check cannalUpdateVue: Quit");
				      
				      // Update la vue IHM
				         fenetre.afficheBodyVuConference(roleUser, value, eConf.getIdConferenceActuel());
//			       }

			      // Vérification si je dois couper l'éméteur
			         for (int i = 1; i < value.length; i++) {
			        	 logger.log(Level.INFO,"DN TAb: "+value[i][0]);
			        	 int newValeurMicro = new Integer(value[i][1].toString());
			        	 String dnCourent = eConf.getDnUtilisateur();
			        	 String dnLigne = value[i][0].toString();
			        	 logger.log(Level.INFO,"newValeurMicro: "+newValeurMicro);
			        	 logger.log(Level.INFO,"Constantes.MICRO_SPEAK: "+Constantes.MICRO_SPEAK);
						// On ignore la premiere ligne car les conférenciés gèrent ts seul l'ouverture ou la fermeture de l'Emetteur
			        	 // Kill l'emetteur si il existe
			        	 if (dnLigne.equals(dnCourent) && isCommunication && newValeurMicro != Constantes.MICRO_SPEAK){
			        		 // On demande a l'utilisateur d'erreter de parler
			        		 RTPManager[] emetteur = Emetteur_client.rtpm;
							emetteur[0].dispose();
							// Close Thread
							eConf.getConference().getEmetteur().closeThread();
			        		isCommunication = false;
			        		logger.log(Level.INFO,"Check cannalUpdateVue: Stop Emetteur");
			        	 }
			        	 // Start l'emmeteur si l'utilisateur est en communication
			        	 if (dnLigne.equals(dnCourent) && !isCommunication && newValeurMicro == Constantes.MICRO_SPEAK){
			        		 // Un utilisateur vient d'avoir le droit de parler
			        		 logger.log(Level.INFO,"Ip Serveur: "+eConf.getIp_Serveur());
			        		 logger.log(Level.INFO,"Port d'écoute Serveur: "+eConf.getPortEmetteurDuServeur());
			        		Emetteur_client emetteur = new Emetteur_client(eConf.getPortEmetteurDuServeur(), eConf.getIp_Serveur());
			        		eConf.getConference().setEmetteur(emetteur);
			        		emetteur.start();
			        		isCommunication = true;
			        		logger.log(Level.INFO,"Check cannalUpdateVue: Start Emetteur");
			        	 }
					}
			         logger.log(Level.INFO,"Check cannalUpdateVue: Quit");
			      
			      // Update la vue IHM
			         fenetre.afficheBodyVuConference(roleUser, value, eConf.getIdConferenceActuel());
			       } 
			       
				 }catch (Exception e) {
				 logger.log(Level.SEVERE," ---> Erreur en creant le flux de entré : ");
				 logger.log(Level.SEVERE,e.getClass() + ": " +  e.getMessage(), e);
				 }
				}	
			}

}
